package com.tetris;

import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.View;

// ████
class Block2 extends Block {
    /**
     * 构造方法。
     */
    public Block2() {
        for (int j = 0; j < Const.BLOCK_GRID_COUNT_V; j++) {
            mBlocks[1][j].mUsed = true;
        }
    }

    /**
     * 进入预览区域。
     * @param preview   预览区域
     * @param drawer    绘图者
     */
    public void enterPreview(View preview, Canvas drawer) {
        final int x = preview.getWidth() / 2 - Const.GRID_SIZE * 2;
        final int y = (preview.getHeight() - Const.GRID_SIZE) / 2;

        for (int j = 0; j < Const.BLOCK_GRID_COUNT_H; j++) {
            mPaint.setColor(mColor);
            drawer.drawRect(x + Const.GRID_SIZE * j, y, x + Const.GRID_SIZE * j + Const.GRID_SIZE, y + Const.GRID_SIZE, mPaint);
            Block.drawEdge(drawer, x + Const.GRID_SIZE * j, y, mPaint);
        }
    }

    /**
     * 擦除。
     */
    protected void erase() {
        final Rect rect = new Rect();

        switch (mShape) {
            case ONE:
                rect.set(Const.GRID_SIZE * mLine, Const.GRID_SIZE * (mRow + 1), Const.GRID_SIZE * (mLine + 4), Const.GRID_SIZE * (mRow + 2));
                break;
            case TWO:
                rect.set(Const.GRID_SIZE * (mLine + 1), Const.GRID_SIZE * mRow, Const.GRID_SIZE * (mLine + 2), Const.GRID_SIZE * (mRow + 4));
                break;
        }
        super.eraseRect(rect);
    }

    /**
     * 获取底端所在的行数。底端是指方块最下方的有效格。
     * @return 底端所在的行数
     */
    public int getBottom() {
        if (mShape == Shape.ONE) {
            return mRow + 1;
        }
        return mRow + 3;
    }

    /**
     * 获取顶端所在的行数。顶端是指方块最上方的有效格。
     * @return 顶端所在的行数
     */
    public int getTop() {
         if (mShape == Shape.ONE) {
            return mRow + 1;
         }
         return mRow;
    }

    /**
     * 对不能下落的处理。
     */
    protected void handleCannotMoveDown() {
        switch (mShape) {
            case ONE:
                for (int j = 0; j < Const.BLOCK_GRID_COUNT_H; j++) {
                    Game.sExistentBlocks[mRow + 1][mLine + j].mUsed = true;
                    Game.sExistentBlocks[mRow + 1][mLine + j].mColor = mColor;
                }
                break;
            case TWO:
                for (int i = 0; i < Const.BLOCK_GRID_COUNT_V; i++) {
                    Game.sExistentBlocks[mRow + i][mLine + 1].mUsed = true;
                    Game.sExistentBlocks[mRow + i][mLine + 1].mColor = mColor;
                }
                break;
        }
    }

    /**
     * 下落。
     * @return 成功则返回 true，否则为 false
     */
    public boolean moveDown() {
        switch (mShape) {
            case ONE:
                if (mRow == 18) {
                    this.handleCannotMoveDown();
                    return false;
                }
                for (int i = 0; i < Const.BLOCK_GRID_COUNT_H; i++) {
                    if (Game.sExistentBlocks[mRow + 2][mLine + i].mUsed) {
                        this.handleCannotMoveDown();
                        return false;
                    }
                }
                break;
            case TWO:
                if (mRow == 16) {
                    this.handleCannotMoveDown();
                    return false;
                }
                if (Game.sExistentBlocks[mRow + 4][mLine + 1].mUsed) {
                    this.handleCannotMoveDown();
                    return false;
                }
                break;
        }

        return super.moveDown();
    }

    /**
     * 左移。
     */
    public void moveLeft() {
        switch (mShape) {
            case ONE:
                if (mLine == 0) {
                    return;
                }
                if (Game.sExistentBlocks[mRow + 1][mLine - 1].mUsed) {
                    return;
                }
                break;
            case TWO:
                if (mLine == -1) {
                    return;
                }
                for (int i = 0; i < Const.BLOCK_GRID_COUNT_V; i++) {
                    if (Game.sExistentBlocks[mRow + i][mLine].mUsed) {
                        return;
                    }
                }
                break;
        }

        super.moveLeft();
    }

    /**
     * 右移。
     */
    public void moveRight() {
        switch (mShape) {
            case ONE:
                if (mLine == 6) {
                    return;
                }
                if (Game.sExistentBlocks[mRow + 1][mLine + 4].mUsed) {
                    return;
                }
                break;
            case TWO:
                if (mLine == 8) {
                    return;
                }
                for (int i = 0; i < Const.BLOCK_GRID_COUNT_V; i++) {
                    if (Game.sExistentBlocks[mRow + i][mLine + 2].mUsed) {
                        return;
                    }
                }
                break;
        }

        super.moveRight();
    }

    /**
     * 变形。
     */
    public void transform() {
        switch (mShape) {
            case ONE:
                if (mRow == -1 || mRow >= 17) {
                    return;
                }
                if (Game.sExistentBlocks[mRow][mLine + 1].mUsed ||
                        Game.sExistentBlocks[mRow + 2][mLine + 1].mUsed ||
                        Game.sExistentBlocks[mRow + 3][mLine + 1].mUsed) {
                    return;
                }
                this.erase();
                mBlocks[1][0].mUsed = mBlocks[1][2].mUsed = mBlocks[1][3].mUsed = false;
                mBlocks[0][1].mUsed = mBlocks[2][1].mUsed = mBlocks[3][1].mUsed = true;
                mShape = Shape.TWO;
                break;
            case TWO:
                if (mLine == -1 || mLine >= 7) {
                    return;
                }
                if (Game.sExistentBlocks[mRow + 1][mLine].mUsed ||
                        Game.sExistentBlocks[mRow + 1][mLine + 2].mUsed ||
                        Game.sExistentBlocks[mRow + 1][mLine + 3].mUsed) {
                    return;
                }
                this.erase();
                mBlocks[1][0].mUsed = mBlocks[1][2].mUsed = mBlocks[1][3].mUsed = true;
                mBlocks[0][1].mUsed = mBlocks[2][1].mUsed = mBlocks[3][1].mUsed = false;
                mShape = Shape.ONE;
                break;
        }

        super.draw();
    }
}
